package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.sys.modules.models.SysCurrency;
import cn.wizzer.app.sys.modules.models.constant.CurrencyConstant;
import cn.wizzer.app.sys.modules.services.SysCurrencyService;
import cn.wizzer.app.user.modules.models.TrialFund;
import cn.wizzer.app.user.modules.models.enums.BizTypeEnum;
import cn.wizzer.app.user.modules.models.vo.TrialFundVo;
import cn.wizzer.app.user.modules.services.TrialFundService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.user.modules.services.account.UserAccountRecordService;
import cn.wizzer.app.user.modules.services.account.UserAccountService;
import cn.wizzer.framework.base.model.enums.BizExceptionEnum;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.framework.util.Id;
import cn.wizzer.framework.util.Result;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.math.BigDecimal;

/**
 * 体验金业务实现
 */
@IocBean(args = {"refer:dao"})
@Service(interfaceClass = TrialFundService.class)
public class TrialFundServiceImpl extends BaseServiceImpl<TrialFund> implements TrialFundService {
    private static final Log log = Logs.get();

    // 查询公共方法
    @Inject
    private CommonDBService dbService;

    // 用户
    @Inject
    private UserService userService;

    @Inject
    private UserAccountRecordService recordService;

    @Inject
    private UserAccountService accountService;

    @Inject
    @Reference
    private SysCurrencyService currencyService;


    public TrialFundServiceImpl(Dao dao) {
        super(dao);
    }


    /**
     * 查询列表（分页）
     *
     * @param userKeyword 昵称或用户名
     * @param searchDate  日期时间
     * @param pageNumber  当前页
     * @param pageSize    显示页数
     * @return
     */
    @Override
    public Pagination listPage(String userKeyword, String[] searchDate, int pageNumber, int pageSize) {
        Sql sql = Sqls.create("SELECT tf.id, u.nickName, u.userName, tf.ip, tf.no, tf.track, tf.profit30, tf.ctAt FROM trial_fund tf " +
                "LEFT JOIN user u ON u.id = tf.userId $condition ");

        Cnd cnd = Cnd.where("tf.delFlag", "=", 0);
        // 昵称或ip
        if (Strings.isNotBlank(userKeyword)) {
            cnd.and(Cnd.exps("tf.ip", "=", userKeyword)
                    .or("u.userName", "=", userKeyword));
        }
        // 时间
        if (searchDate != null && searchDate.length > 0) {
            cnd.and("tf.ctAt", ">=", Times.d2TS(Times.D(searchDate[0])));
            cnd.and("tf.ctAt", "<=", Times.d2TS(Times.D(searchDate[1])));
        }
        sql.setCondition(cnd);
        sql.appendSourceSql("ORDER BY tf.ctAt DESC");

        return dbService.listPage(TrialFundVo.class, pageNumber, pageSize, sql.toString());
    }

    /**
     * 申请体验金
     *
     * @param appid 用户id
     * @param ip    请求ip
     */
    @Override
    @Aop(TransAop.REPEATABLE_READ)
    public void apply(String appid, String ip) {
        // 一个账号只能申请一次
        int userIdCount = this.count(Cnd.where("userId", "=", appid));
        if (userIdCount != 0) {
            Result.breakWith(BizExceptionEnum.EXP_ACCOUNT_FIRST_APPLICATION);
        }
        // 一个ip只能申请一次
        int ipCount = this.count(Cnd.where("ip", "=", ip));
        if (ipCount != 0) {
            Result.breakWith(BizExceptionEnum.EXP_IP_FIRST_APPLICATION);
        }
        // 注册时间为14天以下才可申请 时间戳 86400 × 14
        int count = userService.count(Cnd.where("id", "=", appid)
                .and("ctAt", ">=", Times.getTS() - 1209600));
        if (count == 0) {
            // 注册时间为14天以下才可申请
            Result.breakWith(BizExceptionEnum.EXP_REGISTER_FOURTEEN_FIRST_APPLICATION);
        }
        // 新增数据
        TrialFund trialFund = new TrialFund();
        trialFund.setUserId(appid);
        trialFund.setIp(ip);
        trialFund.setNo(Id.createOrderNo());
        TrialFund insert = this.insert(trialFund);
        // 发放体验金200
        SysCurrency currency = currencyService.fetch(Cnd.where("name", "=", CurrencyConstant.EXP));
        recordService.add(currency.getId(), appid, BigDecimal.valueOf(200), BizTypeEnum.TRIAL_FUND_GIVE_OUT, insert.getId(), trialFund.getNo());
        log.info("体验金发放，userId：" + appid + ",ip:" + ip + ",no:" + trialFund.getNo());

    }

}
